<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Freelancer;
use App\Models\FreelancerFourElementLog;
use App\Services\FourElement\FourElementVerifier;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\MessageBag;
use Illuminate\Validation\Rule;

class FreelancerController extends Controller
{
    public function __construct(private readonly FourElementVerifier $fourElementVerifier)
    {
    }

    public function index(Request $request)
    {
        $query = Freelancer::query()->with(['tasks:id,name']);

        if ($request->filled('name')) {
            $query->where('name', 'like', '%' . $request->name . '%');
        }

        if ($request->filled('phone')) {
            $query->where('phone', 'like', '%' . $request->phone . '%');
        }

        if ($request->filled('id_card')) {
            $query->where('id_card', 'like', '%' . $request->id_card . '%');
        }

        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        $allowedSortBy = ['name', 'phone', 'status', 'created_at'];
        $sortBy = $request->get('sort_by', 'name');
        if (! in_array($sortBy, $allowedSortBy, true)) {
            $sortBy = 'name';
        }
        $sortOrder = strtolower($request->get('sort_order', 'asc')) === 'desc' ? 'desc' : 'asc';

        $perPage = (int) $request->get('per_page', 15);

        $paginator = $query->orderBy($sortBy, $sortOrder)->paginate($perPage);

        $collection = $paginator->getCollection()->map(function (Freelancer $freelancer) {
            return $this->transformFreelancer($freelancer);
        });

        $paginator->setCollection($collection);

        return response()->json([
            'code' => 0,
            'message' => '获取自由职业者列表成功',
            'data' => $paginator,
        ]);
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'phone' => ['required', 'string', 'max:50', Rule::unique('freelancers', 'phone')],
            'name' => ['required', 'string', 'max:100'],
            'id_card' => ['required', 'string', 'size:18', Rule::unique('freelancers', 'id_card')],
            'bank_account' => ['required', 'string', 'max:30'],
            'bank_name' => ['nullable', 'string', 'max:100'],
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();

            return response()->json([
                'code' => 1,
                'message' => $this->buildValidationMessage($errors),
                'data' => $errors,
            ], 422);
        }

        $phone = trim($request->input('phone'));
        $name = trim($request->input('name'));
        $idCard = strtoupper(trim($request->input('id_card')));
        $bankAccount = trim($request->input('bank_account'));
        $bankName = $request->filled('bank_name') ? trim($request->input('bank_name')) : null;

        $payload = [
            'name' => $name,
            'phone' => $phone,
            'id_card' => $idCard,
            'bank_account' => $bankAccount,
        ];

        try {
            $result = $this->fourElementVerifier->verify($name, $phone, $idCard, $bankAccount);

            if (! $result->passed) {
                return response()->json([
                    'code' => 1,
                    'message' => $result->message ?? '四要素验证失败',
                    'data' => null,
                ], 422);
            }

            return DB::transaction(function () use ($payload, $bankName, $result) {
                $freelancer = Freelancer::create([
                    'name' => $payload['name'],
                    'phone' => $payload['phone'],
                    'email' => '',
                    'id_card' => $payload['id_card'],
                    'bank_account' => $payload['bank_account'],
                    'bank_name' => $bankName,
                    'status' => 'active',
                    'verification_status' => Freelancer::VERIFICATION_APPROVED,
                    'id_card_recognition_status' => Freelancer::RECOGNITION_APPROVED,
                    'face_recognition_status' => Freelancer::RECOGNITION_PENDING,
                ]);

                FreelancerFourElementLog::create([
                    'freelancer_id' => $freelancer->id,
                    'request_payload' => $payload,
                    'response_payload' => [
                        'passed' => $result->passed,
                        'message' => $result->message,
                        'code' => $result->code,
                        'context' => $result->context,
                    ],
                    'status' => 'passed',
                    'message' => $result->message,
                ]);

                return response()->json([
                    'code' => 0,
                    'message' => '自由职业者创建成功',
                    'data' => $this->transformFreelancer($freelancer->load('tasks:id,name')),
                ], 201);
            });
        } catch (\Throwable $exception) {
            Log::error('[Admin] Create freelancer failed', [
                'error' => $exception->getMessage(),
            ]);

            return response()->json([
                'code' => 1,
                'message' => '创建自由职业者失败，请稍后重试',
                'data' => null,
            ], 500);
        }
    }

    public function show(Freelancer $freelancer)
    {
        $freelancer->load('tasks:id,name');

        return response()->json([
            'code' => 0,
            'message' => '获取自由职业者详情成功',
            'data' => $this->transformFreelancer($freelancer),
        ]);
    }

    public function update(Request $request, Freelancer $freelancer)
    {
        $validator = Validator::make($request->all(), [
            'phone' => ['sometimes', 'string', 'max:50', Rule::unique('freelancers', 'phone')->ignore($freelancer->id, 'id')],
            'name' => ['sometimes', 'string', 'max:100'],
            'id_card' => ['sometimes', 'string', 'size:18', Rule::unique('freelancers', 'id_card')->ignore($freelancer->id, 'id')],
            'bank_account' => ['sometimes', 'nullable', 'string', 'max:30'],
            'bank_name' => ['sometimes', 'nullable', 'string', 'max:100'],
            'status' => ['sometimes', Rule::in(['active', 'inactive'])],
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();

            return response()->json([
                'code' => 1,
                'message' => $this->buildValidationMessage($errors),
                'data' => $errors,
            ], 422);
        }

        $data = $validator->validated();

        try {
            $freelancer->fill([
                'name' => array_key_exists('name', $data) ? trim((string) $data['name']) : $freelancer->name,
                'phone' => array_key_exists('phone', $data) ? trim((string) $data['phone']) : $freelancer->phone,
                'id_card' => array_key_exists('id_card', $data) ? strtoupper(trim((string) $data['id_card'])) : $freelancer->id_card,
                'bank_account' => array_key_exists('bank_account', $data) ? ($data['bank_account'] !== null ? trim((string) $data['bank_account']) : null) : $freelancer->bank_account,
                'bank_name' => array_key_exists('bank_name', $data) ? ($data['bank_name'] !== null ? trim((string) $data['bank_name']) : null) : $freelancer->bank_name,
                'status' => array_key_exists('status', $data) ? $data['status'] : $freelancer->status,
            ]);

            $freelancer->save();
        } catch (\Throwable $exception) {
            Log::error('[Admin] Update freelancer failed', [
                'freelancer_id' => $freelancer->id,
                'error' => $exception->getMessage(),
            ]);

            return response()->json([
                'code' => 1,
                'message' => '更新自由职业者失败，请稍后重试',
                'data' => null,
            ], 500);
        }

        return response()->json([
            'code' => 0,
            'message' => '自由职业者更新成功',
            'data' => $this->transformFreelancer($freelancer->fresh('tasks:id,name')),
        ]);
    }

    public function batchAction(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'action' => ['required', Rule::in(['activate', 'deactivate'])],
            'ids' => ['required', 'array', 'min:1'],
            'ids.*' => ['string'],
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();

            return response()->json([
                'code' => 1,
                'message' => $this->buildValidationMessage($errors),
                'data' => $errors,
            ], 422);
        }

        $ids = collect($request->input('ids', []))->filter()->unique()->values();

        if ($ids->isEmpty()) {
            return response()->json([
                'code' => 1,
                'message' => '请选择至少一个自由职业者',
                'data' => null,
            ], 422);
        }

        $query = Freelancer::whereIn('id', $ids);
        $count = $query->count();

        if ($count === 0) {
            return response()->json([
                'code' => 1,
                'message' => '未找到对应的自由职业者',
                'data' => null,
            ], 404);
        }

        try {
            switch ($request->input('action')) {
                case 'activate':
                    $query->update(['status' => 'active']);
                    $message = "已激活 {$count} 个自由职业者";
                    break;
                case 'deactivate':
                    $query->update(['status' => 'inactive']);
                    $message = "已停用 {$count} 个自由职业者";
                    break;
                default:
                    $message = '操作已完成';
            }
        } catch (\Throwable $exception) {
            Log::error('[Admin] Batch action on freelancer failed', [
                'action' => $request->input('action'),
                'ids' => $ids,
                'error' => $exception->getMessage(),
            ]);

            return response()->json([
                'code' => 1,
                'message' => '批量操作失败，请稍后重试',
                'data' => null,
            ], 500);
        }

        return response()->json([
            'code' => 0,
            'message' => $message,
            'data' => null,
        ]);
    }

    private function transformFreelancer(Freelancer $freelancer): array
    {
        $statusLabels = [
            'active' => '启用',
            'inactive' => '停用',
        ];

        $verificationLabels = [
            Freelancer::VERIFICATION_PENDING => '待认证',
            Freelancer::VERIFICATION_APPROVED => '已认证',
            Freelancer::VERIFICATION_REJECTED => '认证失败',
        ];

        return [
            'id' => $freelancer->id,
            'freelancer_id' => $freelancer->id,
            'name' => $freelancer->name,
            'phone' => $freelancer->phone,
            'email' => $freelancer->email,
            'id_card' => $freelancer->id_card,
            'bank_account' => $freelancer->bank_account,
            'bank_name' => $freelancer->bank_name,
            'status' => $freelancer->status,
            'status_label' => $statusLabels[$freelancer->status] ?? $freelancer->status,
            'verification_status' => $freelancer->verification_status,
            'verification_status_label' => $verificationLabels[$freelancer->verification_status] ?? $freelancer->verification_status,
            'task_names' => $freelancer->tasks->pluck('name')->filter()->values()->all(),
            'created_at' => optional($freelancer->created_at)->format('Y-m-d H:i:s'),
            'updated_at' => optional($freelancer->updated_at)->format('Y-m-d H:i:s'),
        ];
    }

    private function buildValidationMessage(MessageBag $errors): string
    {
        $messages = collect($errors->toArray())->flatten()->filter()->unique()->implode('；');

        return $messages ? '参数验证失败：' . $messages : '参数验证失败';
    }
}
